gtkcssshadowvalue: Don't double-apply the alpha to shadows
authorJasper St. Pierre <jstpierre@mecheye.net>
Thu, 31 Jul 2014 16:27:46 +0000 (18:27 +0200)
committerJasper St. Pierre <jstpierre@mecheye.net>
Sat, 2 Aug 2014 22:58:19 +0000 (18:58 -0400)
It turns out that when we were painting the shadows, we painted the them
with the base color once, which contained the alpha, and then blurred it
and used it as a mask for the fill, which has the fill again.

To fix this, always paint the base surface with full alpha. The existing
code applies the blur conditionally sometimes in weird ways, so the code
shuffling fix may not look correct, but be assured it is. If the blur
happens, the new cr we return has the *default* color applied, which is
fully opaque black, which works perfectly against the A8 surface.

The fallback spinner code needs some modification, since it is
intentionally using the alpha to paint the lobes which are "in the past".
Since we shouldn't be hitting this fallback path very often, we use a
temporary group and paint it with paint_with_alpha, even though it is
slow.

gtk/gtkcssshadowvalue.c
gtk/gtkthemingengine.c
gtk/gtkthemingengineprivate.h

index 797062600edfba84af5bb498763ba4f70e9b04f2..064835225fd567193da1cb3498c6ef47f500a1ff 100644 (file)
@@ -391,9 +391,9 @@ _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
                      _gtk_css_number_value_get (shadow->hoffset, 0),
                      _gtk_css_number_value_get (shadow->voffset, 0));
 
+  gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
   cr = gtk_css_shadow_value_start_drawing (shadow, cr);
 
-  gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
   _gtk_pango_fill_layout (cr, layout);
 
   cr = gtk_css_shadow_value_finish_drawing (shadow, cr);
@@ -415,9 +415,8 @@ _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
   cairo_save (cr);
   pattern = cairo_pattern_reference (cairo_get_source (cr));
 
-  cr = gtk_css_shadow_value_start_drawing (shadow, cr);
-
   gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
+  cr = gtk_css_shadow_value_start_drawing (shadow, cr);
 
   cairo_translate (cr,
                    _gtk_css_number_value_get (shadow->hoffset, 0),
@@ -440,14 +439,13 @@ _gtk_css_shadow_value_paint_spinner (const GtkCssValue *shadow,
 
   cairo_save (cr);
 
+  gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
   cr = gtk_css_shadow_value_start_drawing (shadow, cr);
 
   cairo_translate (cr,
                    _gtk_css_number_value_get (shadow->hoffset, 0),
                    _gtk_css_number_value_get (shadow->voffset, 0));
-  _gtk_theming_engine_paint_spinner (cr,
-                                     radius, progress,
-                                     _gtk_css_rgba_value_get_rgba (shadow->color));
+  _gtk_theming_engine_paint_spinner (cr, radius, progress);
 
   cr = gtk_css_shadow_value_finish_drawing (shadow, cr);
 
@@ -503,6 +501,7 @@ draw_shadow (const GtkCssValue   *shadow,
   if (has_empty_clip (cr))
     return;
 
+  gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
   if (blur)
     shadow_cr = gtk_css_shadow_value_start_drawing (shadow, cr);
   else
@@ -513,7 +512,6 @@ draw_shadow (const GtkCssValue   *shadow,
   if (shadow->inset)
     _gtk_rounded_box_clip_path (clip_box, shadow_cr);
 
-  gdk_cairo_set_source_rgba (shadow_cr, _gtk_css_rgba_value_get_rgba (shadow->color));
   cairo_fill (shadow_cr);
 
   if (blur)
index ac4009e6eb8bba6dbd77d7bdf0ccacf32d1ff943..70a8de2f274b7b66729fb1bd22fac03d4f5af284 100644 (file)
@@ -2546,8 +2546,7 @@ gtk_theming_engine_render_handle (GtkThemingEngine *engine,
 void
 _gtk_theming_engine_paint_spinner (cairo_t       *cr,
                                    gdouble        radius,
-                                   gdouble        progress,
-                                   const GdkRGBA *color)
+                                   gdouble        progress)
 {
   guint num_steps, step;
   gdouble half;
@@ -2576,11 +2575,7 @@ _gtk_theming_engine_paint_spinner (cairo_t       *cr,
       gdouble xscale = - sin (i * G_PI / half);
       gdouble yscale = - cos (i * G_PI / half);
 
-      cairo_set_source_rgba (cr,
-                             color->red,
-                             color->green,
-                             color->blue,
-                             color->alpha * t);
+      cairo_push_group (cr);
 
       cairo_move_to (cr,
                      (radius - inset) * xscale,
@@ -2590,6 +2585,9 @@ _gtk_theming_engine_paint_spinner (cairo_t       *cr,
                      radius * yscale);
 
       cairo_stroke (cr);
+
+      cairo_pop_group_to_source (cr);
+      cairo_paint_with_alpha (cr, t);
     }
 
   cairo_restore (cr);
@@ -2620,10 +2618,8 @@ render_spinner (GtkThemingEngine *engine,
                                         radius,
                                         -1);
 
-  _gtk_theming_engine_paint_spinner (cr,
-                                     radius,
-                                     -1,
-                                     &color);
+  gdk_cairo_set_source_rgba (cr, &color);
+  _gtk_theming_engine_paint_spinner (cr, radius, -1);
 
   cairo_restore (cr);
 }
index 1b61eb496a89c1220b3be954c0534fda95a4082e..3f7b8846fe9d95979371a59452a46282fe9d5ae2 100644 (file)
@@ -26,8 +26,7 @@ G_BEGIN_DECLS
 
 void _gtk_theming_engine_paint_spinner (cairo_t       *cr,
                                         gdouble        radius,
-                                        gdouble        progress,
-                                        const GdkRGBA *color);
+                                        gdouble        progress);
 
 GtkCssValue  *_gtk_theming_engine_peek_property (GtkThemingEngine *engine,
                                                  guint             property_id);